/* engine Copyright (C) 2009 Jingul,Kim
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */
package ec.core;

import java.util.LinkedList;

import ec.gfx.GL;
import ec.gfx.Scene;
import ec.gfx.Video;
import ec.sys.Context;
import ec.sys.Display;
import ec.sys.Proc;

/**
 * @since 2009
 * @version 1.0
 * @author <a href="mailto:jingul.kim@gmail.com">Jingul,Kim</a>
 */
public class View extends Display implements Proc {
	private final Context context = new Context();

	private long m_current;

	private long m_lastUpdate;
	private long m_lastDraw;

	private long m_refreshRate = 1000 / 30;
	private boolean m_bFast;

	private LinkedList<Staff> staffs = new LinkedList<Staff>();
	
	private Scene scene;
	
	private Mouse mouse;
	
	private Manager manager = new Manager();
	
	public View() {
		setProc(this);
		
		manager.addDevice(new Video());
	}

	@Override
	public void nextFrame() {
		m_current = System.currentTimeMillis();

		scene.update(m_current - m_lastUpdate);
		m_lastUpdate = m_current;

		if (m_bFast || (m_current - m_lastDraw) > m_refreshRate) {
			scene.render();
			context.swapBuffer();
			m_lastDraw = m_current;
		}
	}

	public void run() {
		if (create()) {
			show();

			initailize();

			dispatch();

			dispose();
		}
	}

	public void initailize() {
		context.make(getHandle());
		
		mouse = new Mouse();
		addStaff(mouse);
		
		putScene(new Scene());

		GL.clearColor(.0f, .0f, .0f, 1.0f);
		setSize(600, 600);
	}

	public void dispose() {
		context.release();
		destroy();
	}

	public static void main(String[] args) {
		View n = new View();
		n.run();
	}

	@Override
	public void nativeProc(int type, int lFlag, int rFlag) {
		switch (type) {
		case 0:
			if(scene != null)
				scene.resize(0, 0, lFlag, rFlag);
		default:
			break;
		}
	}

	@Override
	public void mouseProc(int type, int button, int x, int y) {
		mouse.dispatch(type, button, x, y);
	}

	public void putScene(Scene scene) {
		this.scene = scene;
		
		for(Staff s:staffs) {
			s.changedScene(scene);
		}
	}
	
	public void addStaff(Staff staff) {
		staffs.add(staff);
	}
	
	public void removeStaff(Staff staff) {
		staffs.remove(staff);
	}
	
	public Scene getScene() {
		return scene;
	}
}
